# -*- coding: utf-8 -*-
# created on 2016/5/12

from mathsolver.functions.base import *
from sympy import Abs, sympify, N, S
import re
from mathsolver.functions.sympy_utils import get_all_child
import math


# 相反数的性质
class ShuYuShiShiShu001(BaseFunction):
    def solver(self, *args):
        if len(args) == 2:
            poly1 = args[0].sympify()
            poly2 = args[1].sympify()
        elif len(args) == 1:
            poly1, poly2 = args[0].sympify()
        expr = poly1 + poly2
        self.steps.append(["由相反数的定义得", "%s = 0" % new_latex(expr)])
        self.output.append(BaseEq([expr, S.Zero]))
        self.label.add("相反数的性质")
        return self


# 倒数的性质
class ShuYuShiShiShu002(BaseFunction):
    def solver(self, *args):
        if len(args) == 2:
            poly1 = args[0].sympify()
            poly2 = args[1].sympify()
        elif len(args) == 1:
            poly1, poly2 = args[0].sympify()
        expr = poly1 * poly2
        self.steps.append(["由倒数的定义得", "%s = 1" % new_latex(expr)])
        self.output.append(BaseEq([expr, S.One]))
        self.label.add("倒数的性质")
        return self


# 绝对值的性质
class ShuYuShiShiShu003(BaseFunction):
    def solver(self, *args):
        poly1 = args[0].sympify()
        poly2 = args[1].sympify()
        expr = Abs(poly1)
        self.steps.append(["由绝对值的定义得", self.output_eq([expr, poly2])])
        self.output.append(BaseEq([expr, poly2]))
        self.label.add("绝对值的性质")
        return self


# 求倒数
class ShuYuShiShiShu004(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        self.steps.append(["由倒数的定义得，", "%s的倒数是%s" % (new_latex(poly), new_latex(1 / poly))])
        self.label.add("求倒数")
        self.output.append(BasePoly(1 / poly))
        return self


# 求相反数
class ShuYuShiShiShu005(BaseFunction):
    def solver(self, *args):
        """
        ShuYuShiShiShu005().solver(BasePoly("Abs(-1/5)"))
        :param args: 
        :return: 
        """
        poly = args[0].sympify()
        self.steps.append(["由相反数的定义得，", "%s的相反数是%s" % (new_latex(poly), new_latex(-poly))])
        self.label.add("求相反数")
        self.output.append(BasePoly(-poly))
        return self


# 求绝对值
class ShuYuShiShiShu006(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        value = Abs(poly).simplify()
        self.steps.append(["由绝对值的定义得，", "%s的绝对值是%s" % (new_latex(poly), new_latex(value))])
        self.label.add("求绝对值")
        self.output.append(BasePoly(value))
        return self


# 求底数
class ShuYuShiShiShuDiShu(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        if poly.is_Pow:
            value = poly.args[0]
            self.steps.append(["由指数的定义得，", "%s的底数是%s" % (new_latex(poly), new_latex(value))])
            self.label.add("求底数")
            self.output.append(BaseNumber(value))
            return self
        else:
            ValueError("Unexpected situation")


# 求指数
class ShuYuShiShiShuZhiShu(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        if poly.is_Pow:
            value = poly.args[1]
            self.steps.append(["由指数的定义得，", "%s的指数是%s" % (new_latex(poly), new_latex(value))])
            self.label.add("求指数")
            self.output.append(BaseNumber(value))
            return self
        else:
            ValueError("Unexpected situation")


# 求值的整数部分
class ShuYuShiShiShuZhengShu(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        zhengshu_value = int(poly)
        self.steps.append(['%s的整数部分为：' % new_latex(poly), '%s' % new_latex(zhengshu_value)])
        self.output.append(BaseNumber(zhengshu_value))
        return self


# 求值的小数部分
class ShuYuShiShiShuXiaoShu(BaseFunction):
    def solver(self, *args):
        poly = args[0].sympify()
        zhengshu_value = int(poly)
        self.steps.append(['因为%s<%s<%s' % (new_latex(zhengshu_value), new_latex(poly), new_latex(zhengshu_value + 1)), '所以%s的小数部分为%s' % (new_latex(poly), new_latex(poly - zhengshu_value))])
        self.output.append(BaseNumber(poly - zhengshu_value))
        return self


# 比较大小
class ShuYuShiShiShuIsLarger(BaseFunction):
    def solver(self, *args):
        polys = args[0].sympify()
        values = [list(self.search(poly))[0] if poly.free_symbols else poly for poly in polys]
        nums = [N(poly) for poly in values]
        sort = sorted(zip(polys, nums), key=lambda xx: xx[-1])
        self.steps.append(["", "<".join([new_latex(poly) for poly, _ in sort])])
        self.label.add("比较大小")
        return self


# 科学计数法
class ShuYuShiShiShuKeXue(BaseFunction):
    def solver(self, *args):
        """
        ShuYuShiShiShuKeXue().solver({'poly2': 'G*D*P', 'number3': '5.3', 'number1': '2011'}, "(据-p)(相关-v)(报道-v)(number1-eng)(年-q)(江苏省-ns)(poly2-eng)(总值-n)(达到-v)(number3-eng)(万亿元-m)(将-d)(这-r)(个数-nmath)(据-p)(用科学记数法表示-vmath)(为-p)(what-eng)")
        :param args: 
        :return: 
        """
        exprs, text = args
        expr = None
        items = []
        exprs = dict([(k, re.sub("\\*[a-z]\\*m", "", v)) for k, v in exprs.items()])
        tokens = [word for word in text.split("(") if word]
        subs = [word.split("-")[0] for word in tokens if
                word.split("-")[1].replace(")", "") in ["m", "eng", "q"] or word.split("-")[0] in ["年", "月", "日"]]
        for sub in subs:
            if "what" in sub:
                break
            elif re.match("[a-z]+[0-9]*", sub) and ("number" in sub or "poly" in sub or "partial" in sub):
                sympy = exprs[sub]
                if not re.search("[0-9]", sympy):
                    continue

                if expr:
                    items.append((exprs[expr], ""))
                expr = sub
            else:
                if sub not in ["年", "月", "日"] and expr:
                    items.append((exprs[expr], sub))
                expr = None

        if expr:
            items.append((exprs[expr], None))

        items = list(set(items))
        number = items[-1][0]
        metric = items[-1][1]
        times = 1
        if metric:
            if "亿" in metric:
                times *= 100000000
            elif "万" in metric:
                times *= 10000

        if number.isdigit():
            notation = "%e" % (float(number) * times)
        else:
            poly = sympify(number)
            if poly.free_symbols:
                poly = get_all_child(poly, func=lambda xx: xx.is_Number)[0]
            notation = "%e" % (poly * times)
        first, second = notation.split("e")
        first = first.rstrip("0")
        second = int(second)

        sympy_notation = sympify("%s * 10 ** %s" % (first, second), evaluate=False)
        if metric and times > 1:
            self.steps.append(["用科学计数法表示%s%s：" % (number, metric), "%s * %d = %s" % (items[0][0], times, new_latex(sympy_notation))])
        else:
            self.steps.append(["用科学计数法表示%s：" % number, "%s = %s" % (items[0][0], new_latex(sympy_notation))])
        self.label.add("科学计数法")
        self.output.append(BaseNumber(sympy_notation))
        return self


class ShuYuShiShiShuKaiGenHao(BaseFunction):
    def solver(self, *args):
        assert not args[0].free_symbols()
        eqs = args[0].value
        value = float(args[1].value[5:-1].encode('ascii'))  # 获取根号里的数字
        for eq_item in eqs:
            sqrt_value = float(eq_item[0][5:-1].encode('ascii'))
            chazhi = math.sqrt(sqrt_value / value)
            if chazhi == int(chazhi) or 1 / chazhi == int(1 / chazhi):
                result = float(eq_item[1].encode('ascii')) / chazhi
                self.steps.append(["因为%s=%s/%s" % (new_latex(value), new_latex(sqrt_value), new_latex(sqrt_value / value)), "所以%s=%s/%s=%s" % (new_latex(args[1].value), new_latex(eq_item[1]), new_latex(chazhi), new_latex(result))])
                break
        self.steps.append(["", "故答案为：%s" % new_latex(result)])
        self.output.append(BaseValue(result))
        return self


if __name__ == '__main__':
    pass
